/**
 * class name: iform,
 * copyright: maximus zhang,
 * License: MIT-LICENSE,
 * contact: maximus.zhang@gmail.com,
 * required-js: http://jsease.googlecode.com/svn/trunk/core.js, icalendar.js, iselect.js
 * update: http://jsease.googlecode.com/svn/trunk/iform.js
 * -------
 */
function iform() {
    var A = arguments,
        _ = this;
    _ = ext( _, ext(
        {
        id: 'iform',
        elem: me.body,
        cls: 'ifom',
        action : '',
        method: 'post',
        onsubmit: null,
        onreset: null,
        data:[
                /* {
                type: 'text',
                name: 'iformtext',
                value: '',
                label: '',
                disabled: false,

                readonly: false,
                checked: false,
                multiple: false,
                text: '',
                ico: '',
                selected: false,
                valid:''
                } */
            ]
        }, A[0] ) );

    _.uitype = 'iform';
    _.igrid = {};
    _.iselect = {};
    _.icalendar = {};

    _.elem = $(_.elem) || me.body;

    if ( !/post|get/i.test(_.method) ) {
        _.method = 'post';
    }
}
iform.prototype = {
    setAction : function (a) {
        this.form.attr('action', this.action = a || this.action);
    return this;
    },

    setMethod : function (m) {
        this.form.attr('method', this.method = m || this.method);
    return this;
    },

    validate : function(){
        var err=0;
        for ( var i=0,L=this.data.length;i<L;i++ ){
            if (!this.data[i].name || !p(this.data[i],'valid')){
                continue;
            }
            var n = this.data[i].name,
                ov = this.data[i].valid.jsonCss();
            if (!p(ov, 'type')){
                continue;
            }

            if (hop($$.regx, ov.type)){
                if(!this.form[n]||!this.form[n].value||!$$.regx[ov.type].test(this.form[n].value.trim())){
                    err++;
                    this[n+'_adv'].html(ov.adv||'Error!');
                } else {
                    this[n+'_adv'].html('');
                }
            } else if ( /idcard/i.test(ov.type)) {
                if(!isId(this.form[n].value)){
                    err++;
                    this[n+'_adv'].html(ov.adv||'Error!');
                } else {
                    this[n+'_adv'].empty();
                }
            } else if ( /multi/i.test(ov.type)) {
                if(!hop(jsonForm(this.form), n)){
                    err++;
                    this[n+'_adv'].html(ov.adv||'Error!');
                } else {
                    this[n+'_adv'].empty();
                }
            }
        }
    return err===0;
    },

    setgrid : function (gd) {
        var _ = this;
        if ( hop(this.igrid, 'igrid'+gd.name) ) {
            var og = this.igrid['igrid'+gd.name];
            og.data={};
            og.dhead.empty();
            og.gbody.empty();
            og.dfoot.empty();
        } else {
            var og = this.igrid['igrid'+gd.name] = {data:{}};
            og.root = elm('div');
            og.root.style.cssText = 'height:350px;overflow:auto;clear:both;';
            og.dtable = elm('table').setClass('idatable').appendTo(og.root);
            og.ghead = elm('thead').setClass('dthead').appendTo(og.dtable);
            og.dhead = elm('tr').setClass('dhead').appendTo(og.ghead);
            og.gbody = elm('tbody').setClass('dtbody').appendTo(og.dtable);
            og.gfoot = elm('tfoot').setClass('dtfoot').appendTo(og.dtable);
            og.dfoot = elm('tr').setClass('dfoot').appendTo(og.gfoot);

            var tool = ext({cls:'',add:{label: '&#28155;&#21152;', fn: function(){return false;}}, mod:{label: '&#20462;&#25913;', fn: function(){return false;}}, del:{label: '&#21024;&#38500;', fn: function(){return false;}}}, gd.tool);
            og.item = elm('div');
            p(tool, 'cls') && og.item.addClass(tool.cls);
            og.tool = elm('div').setClass('inav').appendTo(og.item);
            var tleft = elm('div').setClass('ltr').appendTo(og.tool);
            var tladd = elm('div').setClass('item').appendTo(tleft);
            elm('div').setClass('inavsplt').appendTo(tleft);
            var tlmod = elm('div').setClass('item').appendTo(tleft);
            elm('div').setClass('inavsplt').appendTo(tleft);
            var tldel = elm('div').setClass('item').appendTo(tleft);
            og.toadd = elm('a').setClass('nor').attr('href', '#').appendTo(tladd);
            og.tomod = elm('a').setClass('nor').attr('href', '#').appendTo(tlmod);
            og.todel = elm('a').setClass('nor').attr('href', '#').appendTo(tldel);
            elm('span').setClass('txt').html('&#10010;').appendTo(og.toadd).style.cssText="color:green;font-size:18px;line-height:18px;";
            elm('span').setClass('txt').html( tool.add.label ).appendTo(og.toadd);
            elm('span').setClass('txt').html('&#9998;').appendTo(og.tomod).style.cssText="font-size:18px;line-height:18px;";
            elm('span').setClass('txt').html( tool.mod.label ).appendTo(og.tomod);
            elm('span').setClass('txt').html('&#9003;').appendTo(og.todel).style.cssText="color:red;font-size:18px;line-height:19px;font-weight:bold;";
            elm('span').setClass('txt').html( tool.del.label ).appendTo(og.todel);
            og.toadd.onclick = function(){
                if(typeof tool.add.fn=='function'){
                    tool.add.fn(og.setBody);return false;
                } else if(typeof tool.add.fn=='string'){
                    (new Function(tool.add.fn+';return false;'))(og.setBody);
                } else {return false;}
            };
            og.tomod.onclick = function(){
                var fo = jsonForm(_.form);
                if(hop(fo, gd.name+'guid')){
                    var key0=isArray(fo[gd.name+'guid'])?fo[gd.name+'guid'][0]:fo[gd.name+'guid'];
                    if(typeof tool.mod.fn=='function'){
                        tool.mod.fn(og.setBody, ext(og.data[key0],{guid:key0}));
                        return false;
                    } else if(typeof tool.mod.fn=='string'){
                        (new Function(tool.mon.fn+';return false;'))(og.setBody, ext(og.data[key0],{guid:key0}));
                    } else {return false;}
                } else {return false;}
            };
            og.todel.onclick = function(){
                var fo = jsonForm(_.form),
                    chkn = gd.name+'guid';
                if(hop(fo, chkn)){
                    if(isArray(fo[chkn])) {
                        var akey = fo[chkn];
                        for(var k=0, L=akey.length;k<L;k++){
                            var dk={};
                            dk[akey[k]]='';
                            og.setBody(dk,1);
                        }
                    } else {
                        var akey = fo[chkn];
                        var dk={};
                        dk[akey]='';
                        og.setBody(dk,1);
                    }
                }
                if(typeof tool.del.fn=='function'){
                    tool.del.fn(og.setBody);
                    return false;
                } else if(typeof tool.del.fn=='string'){
                    (new Function(tool.del.fn+';return false;'))(og.setBody);
                } else {return false;}
            };

            og.setHead = function () {
                /* grid head */
                var col0 = elm('td').setClass('col0').appendTo(og.dhead);
                for (var i=0, L=gd.grid.length; i<L; i++) {
                    var otit = gd.grid[i],
                        tit = elm('td').setClass(p(otit,'cls')?('col '+otit.cls):'col').html(otit.text||'').appendTo(og.dhead);
                    p(otit,'title') && tit.attr('title', otit.title);
                }
                elm('td').setClass('colnone').appendTo(og.dhead);
            return og;
            };

            og.setFoot = function () {
                og.isum = {};
                for (var key in og.data) {
                    for (var i=0, L=gd.sum.col.length;i<L;i++) {
                        var col = gd.sum.col[i],
                            vcol = isNaN(og.data[key][col]) ? 0 : og.data[key][col]*1.0;
                        if(hop(og.isum, col)){
                            og.isum[col] += vcol;
                        } else {
                            og.isum[col] = vcol;
                        }
                    }
                }
                og.dfoot.empty();
                /* grid foot */
                var col0 = elm('td').setClass('col0').appendTo(og.dfoot).html('&#8721;');
                for (var i=0, L=gd.grid.length; i<L; i++) {
                    var col = gd.grid[i].col,
                        cls = p(gd.grid[i],'cls') ? (' '+gd.grid[i].cls) : '',
                        dsum = elm('td').setClass('col'+cls).html(hop(og.isum,col)?og.isum[col]:'').appendTo(og.dfoot);
                }
                elm('td').setClass('colnone').appendTo(og.dfoot);
            return og;
            };

            og.mouseover = function(item) {
                item.addClass('hover');
            };
            og.mouseout = function(item) {
                item.delClass('hover');
            };
            og.click = function(item){
                var t = item.className.indexOf('checked')!=-1;
                if (t){
                    item.delClass('checked');
                } else {
                    item.addClass('checked');
                }
                try{
                    item.firstChild.firstChild.checked = !t;
                } catch(e) {
                }
            };
            og.setBody = function (od, del) {
                if ( !od ) {
                    return og.setFoot();
                }
                if ( typeof od == 'function' ) {
                    var _data = od();
                } else if (typeof od == 'object') {
                    var _data = od;
                } else {
                    return og.setFoot();
                }
                ext(og.data, _data);

                /* grid body */
                for ( var key in _data ) {
                    var oko = _data[key],
                        did = gd.name+'_'+key;
                    if ( !!del ) {
                        $(did) && $(did).empty().remove() && delete og.data[key];
                        continue;
                    }

                    og.nodata && og.nodata.empty().remove() && delete og.nodata;

                    var ditem = $(did) ? $(did).delClass('checked').delClass('hover').empty()
                            : elm('tr').attr('id', did).setClass('ditem').appendTo( og.gbody );
                    ditem.sectionRowIndex%2==0 && ditem.addClass('odd');

                    ditem.onmouseover = function() {
                        if (this.className.indexOf('checked')!=-1){
                            return false;
                        }
                        og.mouseover(this);
                    };
                    ditem.onmouseout = function() {
                        if (this.className.indexOf('checked')!=-1){
                            return false;
                        }
                        og.mouseout(this);
                    };
                    ditem.onclick = function() {
                        og.click(this);
                    };

                    /* grid body cells */
                    var tdchk = elm('td').setClass('col0').appendTo(ditem),
                        chk = elm('input').attr('type','checkbox').attr('name', gd.name+'guid').attr('value', (hop(oko, 'action')&&oko.action=='addnew'?key:hop(oko, 'guid')?oko.guid:key)).appendTo(tdchk),
                        namedval = hop(oko, gd.name)?(oko[gd.name]+''):key;
                    elm('input').attr('type', 'hidden').attr('name', gd.name).attr('value', namedval).appendTo(tdchk);
                    namedval != key && elm('input').attr('type', 'hidden').attr('name', namedval).attr('value', key).appendTo(tdchk);
                    for (var i=0, L=gd.grid.length; i<L; i++) {
                        if ( !p(gd.grid[i],'col') ) {
                            continue;
                        }
                        var col = gd.grid[i].col,
                            cls = p(gd.grid[i],'cls') ? ' '+gd.grid[i].cls : '',
                            vcol = oko[col],
                            dcol = elm('td').setClass('col'+ cls).html(vcol||'').appendTo(ditem);
                        hop(gd.sum, 'col') && inArray(col, gd.sum.col) && elm('input').attr('type', 'hidden').attr('name', col).attr('value', vcol).appendTo(dcol);
                    }
                    elm('td').setClass('colnone').appendTo(ditem);
                }
                if ( og.gbody.rows.length===0 ) {
                    og.nodata = elm('tr').setClass('ditem odd').appendTo(og.gbody);
                    elm('td').attr('colspan', gd.grid.length+2).setClass('colnone').html('&#27809;&#26377;&#25968;&#25454;').appendTo(og.nodata);
                }
            return og.setFoot();
            };
        }

    return og.setHead().setBody(gd.data);
    },

    add : function (a) {
        if ( !isArray(a) ) {
            return this;
        }

        for ( var i=0, L=a.length; i<L; i++ ) {
            if ( !a[i].name ) {
                continue;
            }

            var exItem = false;
            switch ( a[i].type.toLowerCase() ) {
                case 'hidden':
                    var item = elm('input').attr('type', 'hidden')
                            .attr('name', a[i].name).attr('value', a[i].value)
                            .appendTo(this.form);
                    exItem = true;
                break;
                case 'text':
                case 'password':
                    var item = elm('input').attr('type', a[i].type)
                            .attr('value', a[i].value || '').attr('name', a[i].name)
                            .setClass('fvtxt'+ (a[i].size ? ' '+ a[i].size : '')
                                + (a[i].fontcase ? ' '+ a[i].fontcase : ''));

                    if ( a[i].autofocus ) {
                        item.attr('autofocus', 'autofocus');
                    }
                    if ( a[i].placeholder ) {
                        item.attr('placeholder', a[i].placeholder);
                    }
                    if ( a[i].readonly ) {
                        item.attr('readonly', 'readonly').setClass('fvtxt');
                    }
                    if ( a[i].disabled ) {
                        item.attr('disabled', 'disabled').setClass('fvtxt-disabled');
                    }
                break;
                case 'radio':
                case 'checkbox':
                    var rc = $('&'+ a[i].name);
                    if ( rc && rc.length && rc[0].nodeName == 'INPUT' &&
                        ( rc[0].type == 'radio' || rc[0].type == 'checkbox' ) ) {
                        var div = rc[rc.length-1].parentNode;
                        exItem = true;
                    }

                    var item = elm('input').attr('type', a[i].type).setClass('rdochk')
                        .attr('value', a[i].value).attr('name', a[i].name);

                    if ( a[i].disabled ) {
                        item.attr('disabled', 'disabled');
                    }
                    if ( a[i].checked ) {
                        item.attr('checked', 'checked');
                    }

                    if ( exItem ) {
                        if ( p(a[i], 'label') ) {
                            var lbl = elm('label').after(div).setClass('rclbl');
                            item.appendTo(lbl);
                            var txt = elm('span').after(item).setClass('rctxt').html(a[i].label);
                        }
                    }

                break;
                case 'textarea':
                    var item = elm('textarea').attr('name', a[i].name)
                        .setClass('ftext').html(a[i].value);
                break;
                case 'select':
                    var sels = $('&'+ a[i].name);
                    if ( sels && sels.length && sels[0].nodeName=='SELECT' ) {
                        var item = sels[0],
                            exItem = true;
                    } else {
                        var item = elm('select').attr('name', a[i].name)
                                .setClass('fvsel');
                    }

                    if ( hop(a[i], 'value') ) {
                        var opt = elm('option').attr('value', a[i].value).appendTo(item);
                        opt.text = a[i].text || a[i].value;
                    }

                    if ( hop(a[i], 'opts') ) {
                        var tmpopts = (typeof a[i].opts == 'function' ? a[i].opts() : a[i].opts);
                        if ( isArray(tmpopts) ) {
                            for ( var j=0, K=tmpopts.length; j<K; j++ ) {
                                var opt = elm('option').attr('value', tmpopts[j].value).appendTo(item);
                                opt.text = tmpopts[j].text || tmpopts[j].value;
                                tmpopts[j].selected && opt.attr('selected', 'selected');
                            }
                        }
                    }

                    a[i].multiple && item.attr('multiple', 'multiple');
                    a[i].selected && opt.attr('selected', 'selected');
                break;
                case 'file':
                    var item = elm('input').attr('type', 'file').attr('name', a[i].name).setClass('fvfile');
                    this.form.attr('enctype', 'multipart/form-data').attr('target', 'targifrm');
                    a[i].multiple && item.attr('multiple', 'multiple');
                    a[i].accept && item.attr('accept', a[i].accept);
                break;
                case 'icalendar':
                    if (hop(this.icalendar, 'ical'+ a[i].name)) {
                        var item = this.icalendar['ical'+ a[i].name].item;
                        item.value = '';
                        this.icalendar['ical'+ a[i].name].icalendar.reset();
                    } else {
                        var item = elm('input').attr('type', 'text').attr('name', a[i].name).setClass('fvtxt');
                        a[i].readonly && item.attr('readonly', 'readonly');
                        this.icalendar['ical'+ a[i].name] = {item : item};
                        this.icalendar['ical'+ a[i].name].icalendar = (new icalendar({elem: item, id: this.id+'_ical_'+a[i].name})).init();
                    }
                break;
                case 'iselect':
                    var item = elm('div');
                    if (hop(this.iselect, 'isel'+ a[i].name)){
                        this.iselect['isel'+ a[i].name].clearOpts().addOpts().$.appendTo(item);
                    } else {
                        this.iselect['isel'+ a[i].name] = (new iselect(ext(a[i], {elem: item, id: this.id+'_isel_'+a[i].name, form: this.form }))).init();
                    }
                break;
                case 'igrid':
                        var item = this.setgrid(a[i]).item;
                    if (false && hop(this.igrid, 'igrid'+ a[i].name)) {
                        var item = this.igrid['igrid'+ a[i].name].item;
                    } else {
                    }
                break;
                case 'submit':
                case 'reset':
                    if ( !this.sandbox ) {
                        this.sandbox = elm('div').setClass('fitem fcmd').appendTo( this.form );
                    }
                    var item = elm('button').attr('type', a[i].type).appendTo( this.sandbox ).setClass('cmdbtn');
                    if ( p(a[i], 'ico') ) {
                        var img = elm('img').attr('src', a[i].ico).appendTo(item).setClass('btnico');
                    }
                    var txt = elm('span').setClass('btntxt').appendTo(item).html(a[i].text);
                    exItem = true;
                break;
            }

            if ( !exItem ) {
                var div = elm('div').setClass('fitem');

                if ( this.sandbox ) {
                    div.before(_.sandbox);
                    if (this.form.childNodes.length%2===0) {
                        div.addClass('odd');
                    }
                } else {
                    div.appendTo(this.form);
                    if (this.form.childNodes.length%2==1) {
                        div.addClass('odd');
                    }
                }

                var ftit = elm('div').setClass('ftitle').appendTo(div),
                    fdat = elm('div').setClass('fdata').appendTo(div),
                    ftip = elm('div').setClass('ftip').html(a[i].tips || '').appendTo(fdat);
                    this[a[i].name +'_adv'] = elm('div').setClass('fadv').appendTo(div);

                if (/igrid/i.test(a[i].type)) {
                    if(hop(this.igrid, 'igrid'+a[i].name)){
                        this.igrid['igrid'+a[i].name].root.appendTo(div);
                    }
                }

                var checkbox_radio = false;
                if ( p(a[i], 'label') ) {

                    if ( a[i].type == 'radio' || a[i].type == 'checkbox' ) {
                        checkbox_radio = true;
                        if ( p(a[i], 'text') ) {
                            ftit.html(a[i].text);
                        }
                    }

                    if ( a[i].type.toLowerCase() =='file' && !isNaN(a[i].value) ) {
                        var mfs = elm('input').attr('type', 'hidden').appendTo(div)
                                .attr('name', 'MAX_FILE_SIZE').attr('value', a[i].value);
                    }


                    if ( checkbox_radio ) {
                        var lbl = elm('label').before(ftip).setClass('rclbl'),
                            txt = elm('span').html(a[i].label);
                        item.before(txt.setClass('rctxt').appendTo(lbl));
                    } else {
                        ftit.html(a[i].label);
                        item.before( ftip );
                    }

                } else {
                    item.before( ftip );
                }
            }
        }

    return this;
    },

    reset : function (fo) {
        ext(this, fo);

        if ( this.sandbox ) {
            this.sandbox.empty();
            delete this.sandbox;
        }
        if ( this.icalendar ) {
            for ( var ical in this.icalendar ) {
                this.icalendar[ical].item.value = '';
                this.icalendar[ical].icalendar.reset();
            }
        }

        this.init();
    return this;
    },

    init : function () {
        var _ = this;
        if ( this.form && this.form.nodeName=='FORM') {
            this.form.empty();
        } else {
            this.form = elm('form');
        }

        this.form.attr('id', this.id).setClass(this.cls).attr('enctype', 'application/x-www-form-urlencoded').appendTo(this.elem);
        this.setMethod(this.method).setAction(this.action);

        if ( typeof this.onsubmit == 'function' ) {
            _.form.onsubmit = function () {
                if (!_.validate()){
                    return false;
                }
            return _.onsubmit.apply(this, []);
            };
        } else if ( typeof this.onsubmit == 'string' ) {
            _.form.attr('onsubmit', _.onsubmit);
        }

        if ( typeof this.onreset == 'function' ) {
            _.form.onreset = function () {
            return _.onreset.apply(this, []);
            };
        } else if ( typeof this.onreset == 'string' ) {
            _.form.attr('onreset', _.onreset);
        }

        this.add(this.data);

    return this;
    }
};
